﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Engine
{
    public class ParticleEmitter
    {
        List<Particle> mParticles;
        Matrix matrixRotation;
        Texture2D mTexture;
        Vector2 mPosition;
        Vector2 mParticleVel;
        Random rand;
        float mSpawnDelay;//Cada cuanto salen las particulas
        float timer; //Timer usado para sacar particulas a partir del spawnDelay.
        int mParticlesSpawn;
        int mNoise;

        public ParticleEmitter(Texture2D texture,
                               Vector2 particleVel,
                               Vector2 position,
                               int particlesAmount,//Total amount of particles the emitter will have.
                               float spawnDelay,
                               int particlesSpawn,//How many particles do we spawn each time.
                               float rot)
        {
            mParticles = new List<Particle>();
            mPosition = position;
	        mSpawnDelay = spawnDelay;
	        mParticleVel = particleVel;
            mTexture = texture;
	        mNoise = 0;
	        timer = 0;
            rand = new Random();
            mParticlesSpawn = particlesSpawn;
	        
            for (int i = 0; i < particlesAmount; i++)
            {
                mParticles.Add(new Particle(mPosition, mParticleVel,rot));
            }
        }

        public void Update(GameTime gameTime)
        {
            timer += gameTime.ElapsedGameTime.Milliseconds;
            if (timer > mSpawnDelay)
            {
                timer = 0;
                for (int i = 0; i < mParticlesSpawn; i++)
                    ThrowParticle(mParticleVel, mNoise);
            }

	        for(int i=0; i<mParticles.Count; i++)
	        {
		        if(mParticles[i].IsVisible())
		        {
                    mParticles[i].Update(gameTime);
		        }
	        }
        }

        public void ThrowParticle(Vector2 particleVel,int turbulence)
        {
            float angle = rand.Next(mNoise) - mNoise / 2;
            matrixRotation = Matrix.CreateRotationZ(MathHelper.ToRadians(angle));
            Vector2 ParticleVel = Vector2.Transform(mParticleVel, matrixRotation);

            for (int i = 0; i < mParticles.Count; i++)
            {
                if (!mParticles[i].IsVisible())
                {
                    mParticles[i].SetAlpha(255);
                    mParticles[i].SetPosition(mPosition);
                    mParticles[i].SetVelocity(ParticleVel);
                    mParticles[i].SetIsVisible(true);
                    break;
                }
            }
        }
        
        public void Draw(SpriteBatch spriteBatch)
        {
            foreach (Particle p in mParticles)
            {
                if (p.IsVisible())
                {
                    spriteBatch.Draw(mTexture,
                    p.GetPosition(),
                    new Rectangle(0, 0, mTexture.Width, mTexture.Height),
                    p.GetColor(),
                    p.GetAngle(),
                    new Vector2(mTexture.Width / 2, mTexture.Height / 2),
                    1,
                    0,
                    0);
                }
            }
        }

        #region Sets

        public void SetNoise(int noise){mNoise = noise;}
        public void SetPosition(Vector2 pos){mPosition = pos;}
        public void SetSpawnDelay(float delay){mSpawnDelay = delay;}
        public void SetDecay(float decay)
        {
            for(int i=0; i<mParticles.Count;i++)
	            mParticles[i].SetDecay(decay);
        }
        public void SetRotation(float rotation)
        {
            for (int i = 0; i < mParticles.Count; i++)
                mParticles[i].SetRotation(rotation);
        }

        #endregion

    }
}
